package com.network.retrofit.utils;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.os.Build;
import android.telephony.TelephonyManager;
import android.util.Log;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonSyntaxException;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.internal.bind.ObjectTypeAdapter;
import com.network.retrofit.net.callback.ErrorCallBack;
import com.network.retrofit.net.callback.GsonErrorBack;
import com.network.retrofit.utils.gson.DataTypeAdaptor;
import com.network.retrofit.utils.gson.GsonErrorBean;
import com.network.retrofit.utils.gson.MapTypeAdapter;

import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.Collections;
import java.util.List;

/**
 * 项目: com.network.retrofit.utils
 * 创建人: LuoFG
 * 创建时间: 2021/6/29  10:56
 * 描述:
 * @author android
 */
public class NetWorkBaseUtil {
    private static class InstanceHolder{
        private static NetWorkBaseUtil instance=new NetWorkBaseUtil();
    }

    public static NetWorkBaseUtil getInstance(){
       return InstanceHolder.instance;
    }

    private Gson gson;

    private GsonErrorBack gsonErrorBack=null;

    public NetWorkBaseUtil setGsonErrorBack(GsonErrorBack gsonErrorBack) {
        this.gsonErrorBack = gsonErrorBack;
        return this;
    }

    public Gson getGson(){
        if(gson==null){
            /*gson = new GsonBuilder()
                    .serializeNulls()//序列化null
                    .create();*/
            gson=initDataTypeGson();
        }
        return gson;
    }

    /**
     * @return 初始化Data转换方式
     */
    private Gson initDataTypeGson(){
        GsonBuilder gsonBuilder = new GsonBuilder();
        gsonBuilder.registerTypeAdapterFactory(DataTypeAdaptor.FACTORY);
        gson=gsonBuilder.create();
        return gson;
    }

    private  Gson initSpecialTypeGson(){
        Gson gson = new GsonBuilder().create();
        try {
            Field factories = Gson.class.getDeclaredField("factories");
            factories.setAccessible(true);
            Object o = factories.get(gson);
            Class<?>[] declaredClasses = Collections.class.getDeclaredClasses();
            for (Class c : declaredClasses) {
                if ("java.util.Collections$UnmodifiableList".equals(c.getName())) {
                    Field listField = c.getDeclaredField("list");
                    listField.setAccessible(true);
                    List<TypeAdapterFactory> list = (List<TypeAdapterFactory>) listField.get(o);
                    int i = list.indexOf(ObjectTypeAdapter.FACTORY);
                    list.set(i, MapTypeAdapter.FACTORY);
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return gson;
    }



    public <T>T transGsonData(Object data, Class<T> classOfT, ErrorCallBack... backs){
        T transt=null;
        try {
            if(data instanceof String) {
                String dataTrans=(String)data;
                transt = getGson().fromJson(dataTrans, classOfT);
            }else {
                transt = getGson().fromJson(getGson().toJson(data), classOfT);
            }
        } catch (JsonSyntaxException e) {
            e.printStackTrace();
            if(gsonErrorBack!=null){
                gsonErrorBack.errorBack(new GsonErrorBean(e,data,classOfT.getName()));
            }

            if(backs!=null&&backs.length!=0){
                backs[0].errorBack(e);
            }
        }

        return transt;
    }

    public <T>T transGsonDataType(Object data, Type type, ErrorCallBack... backs){
        T transt=null;
        try {
            if(data instanceof String) {
                String dataTrans=(String)data;
                transt = getGson().fromJson(dataTrans, type);
            }else {
                transt = getGson().fromJson(getGson().toJson(data), type);
            }
        } catch (JsonSyntaxException e) {
            e.printStackTrace();
            if(gsonErrorBack!=null){
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                    gsonErrorBack.errorBack(new GsonErrorBean(e,data,"type="+type.getTypeName()));
                }else{
                    gsonErrorBack.errorBack(new GsonErrorBean(e,data,"type=otherType"));
                }
            }

            if(backs!=null&&backs.length!=0){
                backs[0].errorBack(e);
            }
        }

        return transt;
    }


    /**
     * 判断是否有网络连接
     * @param context
     * @return
     */
    public  boolean isNetworkConnected(Context context) {
        if (context != null) {
            ConnectivityManager mConnectivityManager = (ConnectivityManager) context
                    .getSystemService(Context.CONNECTIVITY_SERVICE);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if (mConnectivityManager != null) {
                    Network networks = mConnectivityManager.getActiveNetwork();
                    NetworkCapabilities networkCapabilities = mConnectivityManager.getNetworkCapabilities(networks);
                    if (networkCapabilities != null) {
                        Log.e("------------有网络", "有网络");
                        return true;
                    } else {
                        Log.e("------------没有网络", "没有网络");
                        return false;
                    }
                }
            }else {
                NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
                if (mNetworkInfo != null) {
                    return mNetworkInfo.isAvailable();
                }
            }
        }
        return false;
    }


    /**
     * 判断WIFI网络是否可用
     * @param context
     * @return
     */
    public  boolean isWifiConnected(Context context) {
        if (context != null) {
            ConnectivityManager mConnectivityManager = (ConnectivityManager) context
                    .getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo mWiFiNetworkInfo = mConnectivityManager
                    .getNetworkInfo(ConnectivityManager.TYPE_WIFI);
            if (mWiFiNetworkInfo != null) {
                return mWiFiNetworkInfo.isAvailable();
            }
        }
        return false;
    }


    /**
     * 判断MOBILE网络是否可用
     * @param context
     * @return
     */
    public  boolean isMobileConnected(Context context) {
        if (context != null) {
            ConnectivityManager mConnectivityManager = (ConnectivityManager) context
                    .getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo mMobileNetworkInfo = mConnectivityManager
                    .getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
            if (mMobileNetworkInfo != null) {
                return mMobileNetworkInfo.isAvailable();
            }
        }
        return false;
    }


    /**
     * 获取当前网络连接的类型信息
     * @param context
     * @return
     */
    public  int getConnectedType(Context context) {
        if (context != null) {
            ConnectivityManager mConnectivityManager = (ConnectivityManager) context
                    .getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
            if (mNetworkInfo != null && mNetworkInfo.isAvailable()) {
                return mNetworkInfo.getType();
            }
        }
        return -1;
    }


    /**
     * 获取当前的网络状态 ：没有网络0：WIFI网络1：3G网络2：2G网络3
     *
     * @param context
     * @return
     */
    public  int getAPNType(Context context) {
        int netType = 0;
        ConnectivityManager connMgr = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
        if (networkInfo == null) {
            return netType;
        }
        int nType = networkInfo.getType();
        if (nType == ConnectivityManager.TYPE_WIFI) {
            netType = 1;// wifi
        } else if (nType == ConnectivityManager.TYPE_MOBILE) {
            int nSubType = networkInfo.getSubtype();
            TelephonyManager mTelephony = (TelephonyManager) context
                    .getSystemService(Context.TELEPHONY_SERVICE);
            if (nSubType == TelephonyManager.NETWORK_TYPE_UMTS
                    && !mTelephony.isNetworkRoaming()) {
                netType = 2;// 3G
            } else {
                netType = 3;// 2G、4G、5G
            }
        }
        NetWorkLogUtil.logE("当前网络类型:"+netType);
        return netType;
    }


    /**
     * 判断是否是wifi连接
     */
    public  boolean isWifi(Context context)
    {
        ConnectivityManager cm = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);

        if (cm == null) {
            return false;
        }
        return cm.getActiveNetworkInfo().getType() == ConnectivityManager.TYPE_WIFI;

    }

    /**
     * 打开网络设置界面
     */
    public  void openSetting(Activity activity)
    {
        Intent intent = new Intent("/");
        ComponentName cm = new ComponentName("com.android.settings",
                "com.android.settings.WirelessSettings");
        intent.setComponent(cm);
        intent.setAction("android.intent.action.VIEW");
        activity.startActivityForResult(intent, 0);
    }
}
